//
//  YMPDFDocument.m
//  TestDemo
//
//  Created by fengxijun on 16/6/23.
//  Copyright © 2016年 goappbox. All rights reserved.
//

#import "YMPDFDocument.h"
#import <CoreGraphics/CGPDFDocument.h>

NSString *errorCodeKey = @"errorCode";

@interface YMPDFDocument ()
{
}
@property (nonatomic, strong) NSString *filepath;
@property (nonatomic, strong) NSString *password;

@property (nonatomic, assign) CGDataProviderRef provider;
@property (nonatomic) CGPDFDocumentRef document;

@end

@implementation YMPDFDocument

@synthesize document=_document,info=_info,catalog=_catalog;

- (void)dealloc {
    if (self.document) {
        CGPDFDocumentRelease(self.document);
    }
}

- (NSString *)generalGUID {
    CFUUIDRef theUUID = CFUUIDCreate(NULL);
    
    CFStringRef theString = CFUUIDCreateString(NULL, theUUID);
    
    NSString *unique = [NSString stringWithString:(__bridge id)theString];
    
    CFRelease(theString); CFRelease(theUUID); // Cleanup CF objects
    
    return unique;
}

- (instancetype) initWithfilepath:(NSString *)filepath
                         passowrd:(NSString *)password
                            error:(NSError *__autoreleasing *)error {
    if (filepath == nil) {
        *error = [NSError errorWithDomain:@"pdf.goappbox.com" code:1011 userInfo:@{NSLocalizedDescriptionKey : @"url参数不能为空",errorCodeKey:@(YMPDFUrlNULL)}];
        return nil;
    }
    self = [super init];
    if (self) {
        self.filepath = filepath;
        self.password = password;
        CFStringRef pathRef = CFStringCreateWithCString(NULL, [filepath UTF8String], kCFStringEncodingUTF8);
        CFURLRef urlRef = CFURLCreateWithFileSystemPath(NULL, pathRef, kCFURLPOSIXPathStyle, NO);
        CFRelease(pathRef);
        self.document = CGPDFDocumentCreateWithURL(urlRef);
        CFRelease(urlRef);
        if ([self isNeedsPassword] && self.document != nil) {
            CGPDFDocumentRelease(self.document);
            self.document = nil;
            *error = [NSError errorWithDomain:@"pdf.goappbox.com" code:1011 userInfo:@{NSLocalizedDescriptionKey : @"需要输入正确的密码",errorCodeKey:@(YMPDFPasswordError)}];
            return nil;
        }
        [self loadExtData];
        if (self.totalPageCount == 0) {
            CGPDFDocumentRelease(self.document);
            self.document = nil;
            *error = [NSError errorWithDomain:@"pdf.goappbox.com" code:1011 userInfo:@{NSLocalizedDescriptionKey : @"不存在任何类容",errorCodeKey:@(YMPDFNoData)}];
            return nil;
        }
        self.GUID = [self generalGUID];
    }
    return self;
}

- (instancetype) initWithProvider:(CGDataProviderRef)provider
                         password:(NSString *)password
                            error:(NSError *__autoreleasing *)error {
    if (provider == nil) {
        *error = [NSError errorWithDomain:@"pdf.goappbox.com" code:1011 userInfo:@{NSLocalizedDescriptionKey : @"provider参数不能为空",errorCodeKey:@(YMPDFProviderNULL)}];
        return nil;
    }
    
    self = [super init];
    if (self) {
        self.provider = provider;
        self.password = password;
        self.document = CGPDFDocumentCreateWithProvider(provider);
        if ([self isNeedsPassword] && self.document != nil) {
            CGPDFDocumentRelease(self.document);
            self.document = nil;
            *error = [NSError errorWithDomain:@"pdf.goappbox.com" code:1011 userInfo:@{NSLocalizedDescriptionKey : @"需要输入正确的密码",errorCodeKey:@(YMPDFPasswordError)}];
            return nil;
        }
        [self loadExtData];
        if (self.totalPageCount == 0) {
            CGPDFDocumentRelease(self.document);
            self.document = nil;
            *error = [NSError errorWithDomain:@"pdf.goappbox.com" code:1011 userInfo:@{NSLocalizedDescriptionKey : @"不存在任何类容",errorCodeKey:@(YMPDFNoData)}];
            return nil;
        }
        self.GUID = [self generalGUID];
    }
    return self;
}

- (BOOL) isNeedsPassword {
    
    if (self.document == nil) {
        return NO;
    }
    
    if (CGPDFDocumentIsEncrypted(self.document) != TRUE) {
        return NO;
    }
    
    if (CGPDFDocumentUnlockWithPassword(self.document, "")) {
        return NO;
    }
    
    if ((_password == nil) || ([_password length] <= 0)) {
        return YES;
    }
    
    char text[128];
    [_password getCString:text maxLength:126 encoding:NSUTF8StringEncoding];
    if (CGPDFDocumentUnlockWithPassword(self.document, text)) {
        return NO;
    }
    
    return YES;
    
}

- (void)loadExtData {
    self.totalPageCount = CGPDFDocumentGetNumberOfPages(self.document);
}

- (YMPDFPage *)pageDataWithPage:(NSUInteger)page {
    if (page > [self totalPageCount]) {
        return nil;
    }
    return [[YMPDFPage alloc] initWithPage:CGPDFDocumentGetPage(self.document, page)];
}

- (YMPDFInfo *)info {
    if (_info == nil) {
        CGPDFDictionaryRef pdfProps = CGPDFDocumentGetInfo(self.document);
        _info = [[YMPDFInfo alloc] initWithDictionary:pdfProps];
    }
    return _info;
}

- (YMPDFCatalog *)catalog {
    if (_catalog == nil) {
        _catalog = [[YMPDFCatalog alloc] initWithDictionary:CGPDFDocumentGetCatalog(self.document)];
    }
    return _catalog;
}

- (NSString *)version {
    int majorVersion, minorVersion;
    CGPDFDocumentGetVersion(self.document, &majorVersion, &minorVersion);
    return [NSString stringWithFormat:@"%d.%d", majorVersion, minorVersion];
}

@end
